/*******************************************************************************
 * 数组查找
 ******************************************************************************/
Array.prototype.indexOf = function(val) {
	for (var i = 0; i < this.length; i += 1) {
		if (this[i] == val) {
			return i;
		}
	}
	return -1;
};

/*******************************************************************************
 * 字符串扩展：清空前后空白
 ******************************************************************************/
String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, "");
};

/*******************************************************************************
 * 字符串扩展：判断开头
 ******************************************************************************/
String.prototype.startWith = function(str) {
	if (str == null || str == "" || this.length == 0 || str.length > this.length)
		return false;
	return this.substr(0, str.length) == str;
}

/*******************************************************************************
 * 字符串扩展：判断结尾
 ******************************************************************************/
String.prototype.endWith = function(str) {
	if (str == null || str == "" || this.length == 0 || str.length > this.length)
		return false;
	return this.substring(this.length - str.length) == str;
}

/*******************************************************************************
 * 字符串扩展：是否为空
 ******************************************************************************/
String.prototype.isNullOrEmpty = function() {
	if (this == null || this == "" || this.length == 0)
		return true;

	var obj = this.replace(/(^\s*)|(\s*$)/g, "");
	if (obj == "" || obj == null || obj.length == 0)
		return true;
	return false;
}

/*******************************************************************************
 * 字符串扩展：转为整数
 ******************************************************************************/
String.prototype.toInt = function(acceptNaN) {
	var val = parseInt(this.trim(), 10);
	return isNaN(val) ? (acceptNaN ? val : 0) : val;
};

/*******************************************************************************
 * 字符串扩展：转为小数
 ******************************************************************************/
String.prototype.toFloat = function(p, acceptNaN) {
	var val = parseFloat(this.trim(), 10);
	if (isNaN(val)) {
		return acceptNaN ? val : 0;
	} else {
		p = p ? p : 0;
		val = parseFloat(val.toPreciseStr(p));
		return val;
	}
};

/*******************************************************************************
 * 数字扩展：按精度格式化成字符串
 ******************************************************************************/
Number.prototype.toPreciseStr = function(p) {
	var num = this;
	p = Math.round(p)

	// 不设置值或小于1，使用默认为2
	if (!p || p < 1) {
		p = 2;
	}

	// 计算放大倍数
	var pow = Math.pow(10, p);
	// 放大并近似取整
	var n = Math.abs(Math.round(num * pow));
	// 计算整数部分的字符串
	var I = n - n % pow + "";
	if (I.length > p) {
		I = I.substr(0, I.length - p);
	}
	// 计算小数部分的字符串
	var F = n % pow + "";
	while (F.length < p) {
		F = "0" + F;
	}
	return (num < 0 ? "-" : "") + I + "." + F;
};

/*******************************************************************************
 * 定义全局操作的命名空间 universal
 ******************************************************************************/
var universal = {};

/*******************************************************************************
 * 重新加载页面，而不是刷新，减少资源文件的加载 (200 from cache 优于304)
 ******************************************************************************/
universal.reload = function(timeout) {
	if (timeout > 0) {
		window.setTimeout(universal.reloadImmediately, timeout);
	} else {
		universal.reloadImmediately();
	}
};
universal.reloadImmediately = function() {
	var url = window.location.href;
	var i = url.indexOf("#");
	url = i > 0 ? url.substring(0, i) : url;
	window.location.replace(url);
};

/*******************************************************************************
 * 获取应用的上下文基本路径
 ******************************************************************************/
universal.getContext = (function() {
	var _context = null;

	var getContext = function() {
		if (_context != null) {
			return _context;
		}
		var url = "";
		$("script").each(function() {
			if (this.src.indexOf("universal.js") > 0) {
				url = this.src;
				return false;
			}
		});
		var vars = [], hash;
		var hashes = url.slice(url.indexOf('?') + 1).split('&');
		for (var i = 0; i < hashes.length; i++) {
			hash = hashes[i].split('=');
			if (hash[0] == "context") {
				_context = hash[1];
				break;
			}
		}
		return _context;
	};
	return getContext;
})();

/*******************************************************************************
 * 加载中，msg 提示消息，msg===false 表示关闭提示
 ******************************************************************************/
universal.modalLoading = (function() {
	var _modal = false;
	function getModal() {
		if (_modal) {
			return _modal;
		}
		var str = [];
		str[str.length] = '<div class="modal" role="dialog" aria-hidden="true">';
		str[str.length] = '<div class="modal-dialog modal-sm">';
		str[str.length] = '<div class="modal-content modal-success">';
		str[str.length] = '<div class="modal-body"><i class="fa fa-spinner fa-spin"></i> <span></span></div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		_modal = $(str.join(""));
		str = null;
		$(document.body).append(_modal);
		return _modal;
	}
	var timeoutId = 0;
	var modalLoading = function(msg) {
		var modal = getModal();
		if (msg === false) {
			modal.modal("hide");
		} else {
			$(".modal-body span", modal).html(msg);
			modal.modal({
				backdrop : "static",
				show : true
			});
		}
	};
	return modalLoading;
})();
/*******************************************************************************
 * 确认对话框，选项：callback, msg, large(可选)
 ******************************************************************************/
universal.modalConfirm = (function() {
	var _modal = false;
	var callback = false;
	function getModal() {
		if (_modal) {
			return _modal;
		}
		var str = [];
		str[str.length] = '<div class="modal" tabindex="-1" role="dialog" aria-hidden="true">';
		str[str.length] = '<div class="modal-dialog">';
		str[str.length] = '<div class="modal-content modal-warning">';
		str[str.length] = '<div class="modal-body"><br><h4></h4></div>';
		str[str.length] = '<div class="modal-footer">';
		str[str.length] = '<button type="button" class="btn btn-info" data-dismiss="modal">取消 Cancel</button>';
		str[str.length] = '<button type="button" class="btn btn-primary" data-dismiss="modal">确认 Confirm</button>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		_modal = $(str.join(""));
		str = null;
		$(document.body).append(_modal);
		$(".btn-primary", _modal).click(function() {
			if (callback) {
				callback();
			}
		});
		return _modal;
	}
	var modalConfirm = function(opt) {
		var modal = getModal();
		$(".modal-dialog", modal).removeClass("modal-lg");
		$(".modal-dialog", modal).removeClass("modal-sm");
		$(".modal-dialog", modal).addClass(opt.large ? "modal-lg" : "modal-sm");
		$(".modal-body h4", modal).html(opt.msg);
		callback = opt.callback;
		modal.modal("show");
	};
	return modalConfirm;
})();

/*******************************************************************************
 * 警告对话框，选项：title, msg, large(可选)
 ******************************************************************************/
universal.modalWarning = (function() {
	var _modal = false;
	function getModal() {
		if (_modal) {
			return _modal;
		}
		var str = [];
		str[str.length] = '<div class="modal" tabindex="-1" role="dialog" aria-hidden="true">';
		str[str.length] = '<div class="modal-dialog">';
		str[str.length] = '<div class="modal-content modal-warning">';
		str[str.length] = '<div class="modal-header">';
		str[str.length] = '<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>';
		str[str.length] = '<h4 class="modal-title"></h4>';
		str[str.length] = '</div>';
		str[str.length] = '<div class="modal-body"></div>';
		str[str.length] = '<div class="modal-footer">';
		str[str.length] = '<button type="button" class="btn btn-danger" data-dismiss="modal">返回 Back</button>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		_modal = $(str.join(""));
		str = null;
		$(document.body).append(_modal);
		return _modal;
	}
	var modalWarning = function(opt) {
		var modal = getModal();
		$(".modal-dialog", modal).removeClass("modal-lg");
		$(".modal-dialog", modal).removeClass("modal-sm");
		$(".modal-dialog", modal).addClass(opt.large ? "modal-lg" : "modal-sm");
		$(".modal-title", modal).html(opt.title);
		$(".modal-body", modal).html(opt.msg);
		modal.modal("show");
	};
	return modalWarning;
})();

/*******************************************************************************
 * 成功提示对话框，选项：msg, large(可选), delay(可选，默认2秒)
 ******************************************************************************/
universal.modalSuccess = (function() {
	var _modal = false;
	function getModal() {
		if (_modal) {
			return _modal;
		}
		var str = [];
		str[str.length] = '<div class="modal" role="dialog" aria-hidden="true">';
		str[str.length] = '<div class="modal-dialog modal-sm">';
		str[str.length] = '<div class="modal-content modal-success">';
		str[str.length] = '<div class="modal-body"></div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		str[str.length] = '</div>';
		_modal = $(str.join(""));
		str = null;
		$(document.body).append(_modal);
		return _modal;
	}
	var timeoutId = 0;
	var modalSuccess = function(opt) {
		var modal = getModal();
		$(".modal-dialog", modal).removeClass("modal-lg");
		$(".modal-dialog", modal).removeClass("modal-sm");
		$(".modal-dialog", modal).addClass(opt.large ? "modal-lg" : "modal-sm");
		$(".modal-body", modal).html(opt.msg);
		modal.modal("show");
		window.clearTimeout(timeoutId);
		var delay = opt.delay ? opt.delay : 2000;
		if (delay > 0) {
			window.setTimeout(function() {
				modal.modal("hide");
			}, delay);
		}
	};
	return modalSuccess;
})();

/*******************************************************************************
 * 切换用户语言
 ******************************************************************************/
universal.switchLocale = function(btn) {
	var btn = $(btn);
	var locale = btn.text().startWith("En") ? "zh" : "en";
	var url = universal.getContext() + "/switchLocale?locale=" + locale;
	$.get(url, function() {
		universal.modalSuccess({
			msg : (locale == "en" ? "Language has been switched to English." : "语言已更改为中文。")
		});
		window.setTimeout(function() {
			btn.html(locale == "en" ? 'En <i class="fa fa-fighter-jet"></i> 中' : '中 <i class="fa fa-fighter-jet"></i> En');
			btn.attr("title", locale == "en" ? "切换语言为中文" : "Switch language to English.");
		}, 1500);
	});

};

/*******************************************************************************
 * 设置 ajax 错误提示
 ******************************************************************************/
universal.setupAjax = function() {
	//
	$.ajaxSetup({
		error : function(request, textStatus, errorThrown) {
			universal.modalLoading(false);
			if (request.status == 401) {
				// 会话超时，提示后自动跳转到登录页面
				window.setTimeout(function() {
					window.open(universal.getContext() + "/login", "_top");
				}, 2000);
			}
			universal.modalWarning({
				title : "出错了 Error Happened",
				msg : request.responseText
			});
		}
	});

};

/*******************************************************************************
 * 扩展 validator 主题样式：紧贴在 input 的下方显示
 ******************************************************************************/
universal.setupValidator = function() {
	var TPL_ARROW = '<span class="n-arrow"><b>◆</b><i>◆</i></span>';
	$.validator.setTheme({
		'yellow_bottom' : {
			formClass : 'n-yellow',
			msgClass : 'n-bottom',
			msgArrow : TPL_ARROW
		}
	});
};

/*******************************************************************************
 * 单选按钮组
 ******************************************************************************/
universal.enableRadioBtnGroup = function() {
	$.fn.radioBtnGroup = function(initVal) {
		$("input", this).each(function() {
			var input = $(this);
			if (input.val() == initVal) {
				input.attr("checked", true);
				input.parent().addClass("active");
				$("i", input.parent()).removeClass("fa-square-o").addClass("fa-check-square-o");
			}
		});
		$(".btn", this).click(function() {
			var btn = $(this);
			$("i", btn.parent()).removeClass("fa-square-o").removeClass("fa-check-square-o").addClass("fa-square-o");
			$("i", btn).removeClass("fa-square-o").addClass("fa-check-square-o");
		});
	}
};

/*******************************************************************************
 * 当滚动高度大于表头高度时，显示固定表头
 ******************************************************************************/
universal.enableFixedThead = function() {
	$.fn.fixedThead = function() {
		$(this).each(function() {

			var dataHead = $(this);
			var dataTable = dataHead.parent();
			var fixedHead = null;
			var fixedTable = null;

			function checkCloneFixedHead() {
				if (fixedHead) {
					return;
				}
				// 预处理，单元格的内容用 div 包裹，并定死div的宽度
				var widths = new Array();
				$("td,th", dataHead).each(function(i) {
					widths[i] = $(this).width();
				});
				$("td,th", dataHead).each(function(i) {
					$(this).wrapInner("<div></div>");
					$(">div", this).width(widths[i]);
				});
				fixedHead = dataHead.clone();
				fixedTable = $(dataTable.get(0).cloneNode(0));
				// 读取手工设置的偏移，再加2像素
				var top = parseInt(fixedHead.css("top"));
				fixedTable.css("width", dataTable.outerWidth());
				fixedTable.css("top", 2 + (top ? top : 0));
				fixedTable.css("position", "fixed");
				fixedTable.hide();
				fixedTable.append(fixedHead);
				fixedTable.appendTo($("body"));
			}

			$(window).scroll(function() {
				if (dataTable.is(":hidden")) {
					return;
				}
				checkCloneFixedHead();
				var scrTop = $(window).scrollTop();
				var headTop = dataHead.offset().top;
				if (scrTop > headTop) {
					fixedTable.show();
				} else {
					fixedTable.hide();
				}
				fixedTable.css("left", dataTable.offset().left - $(window).scrollLeft());
			});

		});
	};
};

/*******************************************************************************
 * 立即初始化
 ******************************************************************************/
$(function() {
	universal.enableRadioBtnGroup();
	universal.enableFixedThead();
	universal.setupValidator();
	universal.setupAjax();
});

/*******************************************************************************
 * 页面 ready 初始化
 ******************************************************************************/
$(document).ready(function() {
	// 取消表单的自动填充
	$("form").each(function() {
		$(this).attr("autocomplete", "off");
	});
});
